<?php
$loader->requireOnce('includes/Utils.class.php');
$loader->requireOnce('includes/PaymentException.class.php');
$loader->requireOnce('ordo/PayPayment.class.php');
$loader->requireOnce('ordo/PayPaymentItem.class.php');
$loader->requireOnce('includes/PaymentProcessor.class.php');
$loader->requireOnce('ordo/PayReceipt.class.php');
/**
 * Controller for out patient payment collection
 *
 * @package modules.billing.controllers
 * @author ppdong
 * @version $Id$
 */
class C_InsurancePayment extends Controller {
    private $logger;

    function __construct($template_mod = "general") {
        parent::Controller();
        $this->template_mod = $template_mod;
        $this->logger = LoggerManager::getLogger('module.billing.controllers.C_InsurancePayment');
        $this->view->path   =   "insurance_payment";
        if (Celini::getCurrentController() == 'InsurancePayment') {
            $menu =& Menu::getInstance();
            $menu->currentSection = 'patient';
        }
        $orders =   L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);
    }

    /**
     * Main working page for insurance payment.
     *
     * @return html Page
     */
    public function actionViewPayment() {
        return $this->view->render('view_payment.html');
    }

    /**
     * Page for input and view payment item of a ticket.
     *
     * @param int $ticketId Ticket Id
     * @return html Result
     */
    public function actionEditServiceListAjax($ticketId = 0) {
        if (isset($_GET['ticketId'])) {
            $ticketId   =   $_GET['ticketId'];
        }
        $medicineUnitList = Utils::getEnumArrayKey(EnumerationConstant::PHA_IMSE_UNIT);
        $this->assign('ticketId', $ticketId);
        $this->assign('medicineUnitList', $medicineUnitList);
        $this->assign('paymentItemList', $this->renderItemList($ticketId));

        return $this->view->render('payment_detail_service_list.html');
    }

    
    /**
     * Render payment summary information of given ticket.
     *
     * @param int $ticketId Ticket Id
     * @return json Result object
     */
    private function renderPaymentSummary($ticketId, $readOnly = false) {
        // Summary payment info
        $objPayment         =   Celini::newORDO('PayPayment')->getObjectByTicket($ticketId);
        $grandTotal         =   EnforceType::int($objPayment->get('original_price'));
        $insurancePrice     =   EnforceType::int($objPayment->get('insurance_price'));
        $patientPrice       =   EnforceType::int($objPayment->get('patient_price'));
        $realPayment        =   EnforceType::int($objPayment->get('real_payment'));
        $remainingAmount    =   max(array($patientPrice - $realPayment, 0));
        // Money amount info
        $this->assign('grandTotal', L10nHelper::renderNumber($grandTotal));
        $this->assign('insurancePrice', L10nHelper::renderNumber($insurancePrice));
        $this->assign('patientPrice', L10nHelper::renderNumber($patientPrice));
        $this->assign('realPayment', L10nHelper::renderNumber($realPayment));
        $this->assign('remainingAmount', L10nHelper::renderNumber($remainingAmount));
        // Cashier
        $cashierId  =   $this->_me->get_person_id();
        $employee   =   Celini::newORDO('Employee', $cashierId);
        $this->assign('cashierName', $employee->get('name'));
        // TicketId
        $this->assign('ticketId', $ticketId);
        // Current receipt code
        $this->assign('receiptCode', PayReceipt::getCurrentCode());
        if ($readOnly) {
            return $this->view->render('closed_payment_summary.html');
        }
        return $this->view->render('payment_detail_summary.html');
    }


    /**
     * Render payment items of given ticket
     *
     * @param int $ticketId Ticket Id
     * @return html List of payment items in a table-format
     */
    private function renderItemList($ticketId, $readOnly = false) {
        $serviceType    =   EnumerationConstant::PAYMENT_ITEM_TYPE_SERVICE_KEY;
        $medTypes       =   EnumerationConstant::PAYMENT_ITEM_TYPE_MEDICINE_KEY;
        $serviceList    =   PayPaymentItem::getPaymentItemsByTicket($ticketId, $serviceType);
        $medicineList   =   PayPaymentItem::getPaymentItemsByTicket($ticketId, $medTypes);
        $this->assign('serviceList', $serviceList);
        $this->assign('serviceType', $serviceType);
        $this->assign('medicineList', $medicineList);
        $this->assign('medicineType', $medTypes);
        $this->assign('ticketId', $ticketId);
        if ($readOnly){
            return $this->view->render('closed_service_list.html');
        }
        return $this->view->render('service_list.html');
    }

    /**
     * View payment details of given ticket
     *
     * @param int $ticketId Ticket Id
     * @return json Result object
     */
    public function actionViewTicketPaymentAjax($ticketId = 0) {
    	$result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
    	if (isset($_GET['ticketId'])) {
    		$ticketId	=	$_GET['ticketId'];
    	}
    	$objTicket =   Celini::newORDO('Ticket', $ticketId);
    	$patientId =   $objTicket->getPatientId();
    	try {
            // Ticket list of the patient
            $ticketList   =   Celini::newORDO('Ticket')->getTicketListByPatient($patientId, EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY,
                false, EnumerationConstant::EXAMINATION_TYPE_INSURANCE_KEY);
            $hisLoader = new HISFileLoader();
            $ctrlPaymentCommon = $hisLoader->getObj('C_PaymentCommon');
            $result['result']['ticketList']    =   $ctrlPaymentCommon->renderTicketListOption($ticketList, $ticketId);
        }
        catch (HISFileLoaderException $e) {
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            return json_encode($result);
        }
        // Check if the ticket is open or closed
        $readOnly  =   true;
        if (strtotime($objTicket->get('created')) >= strtotime(date('Y-m-d'))){
            $readOnly  =   false;
        }
    	// Patient's demographic info
        $objPerson	=   Celini::newORDO('Person',$patientId);
        $objPatient	=   Celini::newORDO('Patient',$patientId);
        $result['result']['patientCode']    =   $objPatient->getPatientCode();
        $result['result']['patientName']    =   $objPerson->getName();
        $objDate    =   DateObject::createFromISO($objPerson->get('date_of_birth'));
        $result['result']['birthDay']       =   $objDate->getYear();
        
        // Insurance information
        $objTicketInsurance =   Celini::newORDO('TicketInsurance')->getLatestObjectByTicket($ticketId);
        $objInsurance       =   Celini::newORDO('Insurance', $objTicketInsurance->get('insurance_id'));
        $result['result']['insuranceCode']      =   $objInsurance->get('insurance_code');
        $result['result']['insuranceUsage']     =   $objInsurance->getIssuedDate() . " - " . $objInsurance->getExpiredDate();
        $result['result']['correctRoute']       =   $objTicketInsurance->getCorrectRoute();
        $result['result']['continous36Month']   =   $objTicketInsurance->getPaidFor36Month();

        // Main content
        $result['result']['mainContent']   =   $this->renderPaymentMainContent($ticketId, $readOnly);

        return json_encode($result);
    }

    /**
     * Add payment item.
     *
     * @return json Result object
     */
    public function actionAddPaymentItemAjax() {
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        $ticketId   =   $_POST['ticketId'];
        $objTicket  =   Celini::newORDO('Ticket', $ticketId);
        $paymentId  =   Celini::newORDO('PayPayment')->getPaymentIdByTicket($ticketId);
        $objPayment =   Celini::newORDO('PayPayment', $paymentId);
        if (EnforceType::int($objPayment->get_id()) == 0) {
            $paymentId   =   $objPayment->createTicketPayment($ticketId);
        }
        // PayPaymentItem object
        $objPayItem     =   Celini::newORDO('PayPaymentItem');
        $serviceName    =   Utils::sanitizeText($_POST['serviceName']);
        $unitPrice      =   L10nHelper::getNumber($_POST['unitPrice']);
        $quantity       =   EnforceType::int($_POST['serviceQuantity']);
        $data   =   array(
            'pay_payment_id'    =>  $paymentId,
            'service_id'        =>  $_POST['serviceId'],
            'service_name'      =>  $serviceName,
            'enum_item_type'    =>  $_POST['itemType'],
            'unit'              =>  $_POST['unitTitle'],
            'unit_price'        =>  $unitPrice,
            'quantity'          =>  $quantity,
            'unit_price'        =>  $unitPrice,
            'original_price'    =>  $unitPrice * $quantity,
            'insurance_price'   =>  0,
            'patient_price'     =>  $unitPrice * $quantity,
            'date'              =>  date('Y-m-d')
        );
        $objPayItem->populateArray($data);
        $objPayItem->persist();

        // Update pay_paymet table
        $objPayment->updatePrices($paymentId);

        // Returned result
        $function =   $_POST['itemListRender'];
        $result['result']['itemList']       =   $this->$function($ticketId);
        $result['result']['paymentSummary'] =   $this->renderPaymentSummary($ticketId);

        return json_encode($result);
    }


    /** Deleting a payment item.
     *
     * @param int $paymentItemId Payment item's Id
     */
    public function actionDeletePaymentItemAjax($paymentItemId = 0) {
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        if (isset($_POST['paymentItemId'])) {
            $paymentItemId  =   $_POST['paymentItemId'];
        }
        $objItem    =   Celini::newORDO('PayPaymentItem', $paymentItemId);
        $paymentId  =   $objItem->get('pay_payment_id');
        $objPayment =   Celini::newORDO('PayPayment', $paymentId);
        $ticketId   =   $objPayment->get('ticket_id');
        // Set status of the payment item to deleted
        $objItem->deletePaymentItem($paymentItemId);
        // Update total patient price of the ticket's payment
        $objPayment->updatePrices($paymentId);
        // Returned result
        $function =   $_POST['itemListRender'];
        $result['result']['itemList']       =   $this->$function($ticketId);
        $result['result']['paymentSummary'] =   $this->renderPaymentSummary($ticketId);

        return json_encode($result);
    }

    public function actionSubmitCollectingAjax() {
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        $ticketId       =   $_POST['ticketId'];
        $this->logger->info("Start action SubmitCollectingAjax {ticketId='$ticketId', amount='". $_POST['amount'] . "'}");

        // 1st: Check if pay_payment record of the ticket existed or not. If not, create one.
        $objPayment =   Celini::newORDO('PayPayment');
        $paymentId  =   $objPayment->getPaymentIdByTicket($ticketId);
        if (!$paymentId) {
            $objPayment->createTicketPayment($ticketId);
            $paymentId  =  $objPayment->get_id();
        }

        // 2nd: Create a receipt of collecting type.
        $paymentType    =   EnumerationConstant::PAYMENT_COLLECTION_TYPE_COLLECTING_KEY;
        $amount         =   L10nHelper::getNumber($_POST['amount']);
        $note           =   Utils::sanitizeText($_POST['note']);
        $cashierId      =   $this->_me->get_person_id();
        $cashierName    =   Celini::newORDO('Employee', $cashierId)->get('name');
        $patientId      =   Celini::newORDO('Ticket', $ticketId)->getPatientId();
        $patientCode    =   Celini::newORDO('Patient', $patientId)->getPatientCode();
        $receiptData =   array(
               'ticket_id'         =>  $ticketId,
               'patient_id'        =>  $patientId,
               'patient_code'      =>  $patientCode,
               'receipt_code'      =>  $_POST['receiptCode'],
               'cashier_id'        =>  $cashierId,
               'cashier_name'      =>  $cashierName,
               'amount'            =>  $amount,
               'note'              =>  $note,
               'enum_payment_type' =>  $paymentType,
               'created_time'      =>  date("Y-m-d H:i")
        );
        $objReceipt     =   Celini::newORDO('PayReceipt');
        $objReceipt->populateArray($receiptData);
        $objReceipt->persist();

        // 3rd: Update total real amount of the ticket payment
        $objReceipt->updateTicketRealPayment($ticketId);
        $this->logger->info("End action SubmitCollectingAjax {ticketId='$ticketId', amount='". $_POST['amount'] . "'}");
        
        // 4th: Set status of the payment items of the ticket to 'collected'
        PayPaymentItem::updateItemStatus($paymentId, PayPaymentItem::COLLECTED);
        
        // Returned result
        $result['result']['paymentSummary'] =   $this->renderPaymentSummary($ticketId);
        $result['result']['itemList']       =   $this->renderItemList($ticketId);

        return json_encode($result);
    }

    public function actionCalculateInsurancePaymentAjax() {
        $ticketId = $_POST['ticketId'];
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        $this->logger->info("Start action CalculateInsurancePaymentAjax {ticketId='$ticketId'}");
        $processor  =   new PaymentProcessor($this);
        $storages   =   $processor->createBillStorages($ticketId);
        $storages[0]->persist();
        $this->logger->info("End action CalculateInsurancePaymentAjax {ticketId='$ticketId'}");

        // Returned result
        $result['result']['itemList']       =   $this->renderItemList($ticketId);
        $result['result']['paymentSummary'] =   $this->renderPaymentSummary($ticketId);

        return json_encode($result);
    }
    
    private function renderPaymentMainContent($ticketId, $readOnly = false) {
        $res    =   '';
        if ($readOnly) {
            // Service list
            $this->assign('serviceList', $this->renderItemList($ticketId, $readOnly));
            // Payment receipt list
            $paymentReceiptList =   '';
            try {
                $hisLoader = new HISFileLoader();
                $ctrlPaymentCommon = $hisLoader->getObj('C_PaymentCommon');
                $_POST['notShowTotal']  =   1;
                $res    =   json_decode($ctrlPaymentCommon->actionViewAdvancePaymentDetails($ticketId), true);
                $paymentReceiptList =   $res['result']['html'];
                
            }
            catch (HISFileLoaderException $e) {
                $paymentReceiptList =   '';
            }
            // Service list part
            $this->assign('paymentReceiptList', $paymentReceiptList);
            // Payment summary
            $this->assign('paymentSummary', $this->renderPaymentSummary($ticketId, $readOnly));
            $res =   $this->view->render('view_closed_payment_detail.html');
        }
        else {
            $this->assign('serviceListPart', $this->actionEditServiceListAjax($ticketId));
            $this->assign('paymentSummary', $this->renderPaymentSummary($ticketId));
            $res =   $this->view->render('view_payment_detail.html');
        }
        return $res;
    }
}
?>